using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Globalization;
using SlimDX;

namespace Barrage.Global
{
    /// <summary>
    /// Set of xml helper functions
    /// </summary>
    public static class XmlHelper
    {
        const string XML_TRUE_ATTRIBUTE = "true";
        const string XML_FALSE_ATTRIBUTE = "false";
        /// <summary>
        /// Gets the string correspondent to the passed boolean value
        /// Useful to ensure parsing is correctly done when loading a generated XML
        /// </summary>
        /// <param name="value">boolean value</param>
        /// <returns>"true" or "false" depending on the value</returns>
        public static string GetBoolValue(bool value)
        {
            return value ? XML_TRUE_ATTRIBUTE : XML_FALSE_ATTRIBUTE;
        }
        /// <summary>
        /// Get the XML attribute value
        /// </summary>
        /// <param name="n">XML node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Attribute value, or the default value if the attribute doesn't exist</returns>
        public static string GetXMLAttribute(XmlNode n, string strAttr,string defaultValue)
        {
            if (n.NodeType != XmlNodeType.Element) return defaultValue;
            if (n == null) return defaultValue;
            XmlAttribute attr = n.Attributes.GetNamedItem(strAttr) as XmlAttribute;
            if (attr != null)
                return attr.Value;
            return defaultValue;
        }

        /// <summary>
        /// Gets the specified attribute of an XmlNode instance
        /// </summary>
        /// <param name="n">XML Node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <returns>Attribute value, or empty string if the attribute is not found</returns>
        public static string GetXMLAttribute(XmlNode n, string strAttr)
        {
            return GetXMLAttribute(n, strAttr, "");
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a integer value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <returns>Parsed integer value, 0 if an error occurs</returns>
        public static int ParseXMLIntAttribute(XmlNode xn, string strAttr)
        {
            return ParseXMLIntAttribute(xn, strAttr, 0);
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a integer value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed integer value, default value if an error occurs</returns>
        public static int ParseXMLIntAttribute(XmlNode xn, string strAttr, int defaultValue)
        {
            int v;
            if (int.TryParse(GetXMLAttribute(xn, strAttr, ""), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out v)) return v;
            return defaultValue;            
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a float value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <returns>Parsed float value, 0 if an error occurs</returns>
        public static float ParseXMLFloatAttribute(XmlNode xn, string strAttr)
        {
            return ParseXMLFloatAttribute(xn, strAttr, 0);
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a float value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="strAttr">Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed float value, default value if an error occurs</returns>
        public static float ParseXMLFloatAttribute(XmlNode xn, string strAttr, float defaultValue)
        {
            float v;
            if (Single.TryParse(GetXMLAttribute(xn, strAttr, ""), NumberStyles.Float, NumberFormatInfo.InvariantInfo, out v)) return v;
            return defaultValue;
        }

        /// <summary>
        /// Parses two attributes of a XML Node to a vector value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="xAttr">X Coordinate Attribute name</param>
        /// <param name="yAttr">Y Coordinate Attribute name</param>
        /// <returns>Parsed vector value, 0 if an error occurs</returns>
        public static Vector2 ParseXMLVector2Attribute(XmlNode xn, string xAttr, string yAttr)
        {
            return GameMath.ParseVector2(GetXMLAttribute(xn, xAttr), GetXMLAttribute(xn, yAttr));
        }

        /// <summary>
        /// Parses two attributes of a XML Node to a vector value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="xAttr">X Coordinate Attribute name</param>
        /// <param name="yAttr">Y Coordinate Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed vector value, default value if an error occurs</returns>
        public static Vector2 ParseXMLVector2Attribute(XmlNode xn, string xAttr, string yAttr, Vector2 defaultValue)
        {
            return GameMath.ParseVector2(GetXMLAttribute(xn, xAttr), GetXMLAttribute(xn, yAttr), defaultValue);
        }

        /// <summary>
        /// Parses three attributes of a XML Node to a vector value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="xAttr">X Coordinate Attribute name</param>
        /// <param name="yAttr">Y Coordinate Attribute name</param>
        /// <param name="zAttr">Z Coordinate Attribute name</param>
        /// <returns>Parsed vector value, 0 if an error occurs</returns>
        public static Vector3 ParseXMLVector3Attribute(XmlNode xn, string xAttr, string yAttr, string zAttr)
        {
            return GameMath.ParseVector3(GetXMLAttribute(xn, xAttr), GetXMLAttribute(xn, yAttr), GetXMLAttribute(xn, zAttr));
        }

        /// <summary>
        /// Parses three attributes of a XML Node to a vector value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="xAttr">X Coordinate Attribute name</param>
        /// <param name="yAttr">Y Coordinate Attribute name</param>
        /// <param name="zAttr">Z Coordinate Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed vector value, default value if an error occurs</returns>
        public static Vector3 ParseXMLVector3Attribute(XmlNode xn, string xAttr, string yAttr, string zAttr, Vector3 defaultValue)
        {
            return GameMath.ParseVector3(GetXMLAttribute(xn, xAttr), GetXMLAttribute(xn, yAttr), GetXMLAttribute(xn, zAttr), defaultValue);
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a color value (must be in hexadecimal format)
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="attr">Attribute name</param>
        /// <returns>Parsed color value, black if an error occurs</returns>
        public static Color4 ParseXMLColorAttribute(XmlNode xn, string attr)
        {
            return GameMath.ParseColor(GetXMLAttribute(xn, attr));
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a color value (must be in hexadecimal format)
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="attr">Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed color value, default if an error occurs</returns>
        public static Color4 ParseXMLColorAttribute(XmlNode xn, string attr, Color4 defaultValue)
        {
            return GameMath.ParseColor(GetXMLAttribute(xn, attr), defaultValue);
        }


        /// <summary>
        /// Parses an attribute of a XML Node to a boolean value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="attr">Attribute name</param>
        /// <returns>Parsed boolean value, False if an error occurs</returns>
        public static bool ParseXMLBoolAttribute(XmlNode xn, string attr)
        {
            return ParseXMLBoolAttribute(xn,attr,false);
        }

        /// <summary>
        /// Parses an attribute of a XML Node to a boolean value
        /// </summary>
        /// <param name="xn">XML Node</param>
        /// <param name="attr">Attribute name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Parsed boolean value, default if an error occurs</returns>
        public static bool ParseXMLBoolAttribute(XmlNode xn, string attr, bool defaultValue)
        {
            string value = GetXMLAttribute(xn, attr);
            if (value == "")
                return defaultValue;
            return value.Equals(XML_TRUE_ATTRIBUTE, StringComparison.InvariantCultureIgnoreCase);
        }

    }
}
